package cn.cnhis.online.mymodule;

import android.util.Log;

import com.google.gson.GsonBuilder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.concurrent.TimeUnit;

import cn.cnhis.online.BuildConfig;
import cn.cnhis.online.mymodule.mybasenet.CachingControlInterceptor;
import cn.cnhis.online.mymodule.sp.MySpUtils;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * baseApi实现
 */
public class BaseApi {
    private static final String TAG = BaseApi.class.getSimpleName();

    public static final int FLAG_FACTORY_GSON = 0;
    public static final int FLAG_FACTORY_STRING = 1;
    public static final int TIMEOUT = 60;
    private static OkHttpClient.Builder builder;

    protected static RetrofitService getRetrofitService(String baseURL) {
        return getRetrofitService(baseURL, FLAG_FACTORY_GSON);
    }

    protected static RetrofitService getRetrofitServiceStr(String baseURL) {
        return getRetrofitService(baseURL, FLAG_FACTORY_STRING);
    }

    protected static RetrofitService getRetrofitService(String baseURL, int factoryFlag) {
        if (!baseURL.startsWith(Constants.HTTP_SERVER_ADDRESS_START))
            baseURL = Constants.HTTP_SERVER_ADDRESS_START + baseURL;
        Log.e(TAG, "BaseApi:getRetrofitService: baseURL==" + baseURL);
        RetrofitService retrofitService = null;
        try {
            retrofitService = new Retrofit.Builder()
                    .baseUrl(baseURL)
                    // 添加Gson转换器
                    .addConverterFactory(getFactory(factoryFlag))
                    // 添加Retrofit到RxJava的转换器
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(httpClient)
                    .build()
                    .create(RetrofitService.class);
        } catch (Exception mE) {
            mE.printStackTrace();
        }
        return retrofitService;
    }

    /**
     * 获取转换器
     *
     * @param flag
     * @return
     */
    private static Converter.Factory getFactory(int flag) {
        switch (flag) {
            case FLAG_FACTORY_GSON:
                return GsonConverterFactory.create(new GsonBuilder()
                        .setLenient()
                        .create()
                );
            case FLAG_FACTORY_STRING:
                return StringConverterFactory.create();
        }
        return StringConverterFactory.create();
    }

    // Retrofit是基于OkHttpClient的，可以创建一个OkHttpClient进行一些配置
    private static OkHttpClient httpClient = new OkHttpClient.Builder()

            .addInterceptor(new CommonParamsInterceptor())
//            .addInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR_OFFLINE)
            .addInterceptor(getLoggerInterceptor())
            .addNetworkInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR)
            .connectTimeout(TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(TIMEOUT, TimeUnit.SECONDS)
            .build();

    /**
     * 日志拦截器
     * 将你访问的接口信息
     *
     * @return 拦截器
     */
    public static HttpLoggingInterceptor getLoggerInterceptor() {
        //日志显示级别
        HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;
        //新建log拦截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.e(TAG, "--->" + message);
            }
        });
        loggingInterceptor.setLevel(level);
        return loggingInterceptor;
    }

    /**
     * Created by wuzhc on 2018/2/2.
     * 公共参数
     */
    public static class CommonParamsInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();
            // 公共的请求方法
            HttpUrl url = original.url().newBuilder()
//                .addQueryParameter(Constants.JSESSIONIDS_KEY, Constants.JSESSIONIDS_VALUE + Constants.KEY_DBNAME_VALUE)
                    .build();
            //添加请求头

            Request.Builder builder = original.newBuilder()
                    .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
                    .addHeader("Connection", "keep-alive")
                    .method(original.method(), original.body())
                    .url(url);
            String sysLoginSessionId = MySpUtils.getSysLoginSessionId(BaseApplication.getINSTANCE());
            if (BuildConfig.DEBUG) Log.d(TAG, "sysLoginSessionId===>"+sysLoginSessionId);
            if (sysLoginSessionId != null) {
                builder.addHeader("sysLoginSessionId", "" + MySpUtils.getSysLoginSessionId(BaseApplication.getINSTANCE()));
            }
            Request request = builder.build();
            return chain.proceed(request);
        }
    }

    public static class StringConverterFactory extends Converter.Factory {
        public static StringConverterFactory create() {
            return new StringConverterFactory();
        }

        public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
            return new StringConverterFactory.ConfigurationServiceConverter();
        }

        final class ConfigurationServiceConverter implements Converter<ResponseBody, String> {

            @Override
            public String convert(ResponseBody value) throws IOException {
                BufferedReader r = new BufferedReader(new InputStreamReader(value.byteStream()));
                StringBuilder total = new StringBuilder();
                String line;
                while ((line = r.readLine()) != null) {
                    total.append(line);
                }
                return total.toString();
            }
        }
    }
}
